package TecMaster.Ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import TecMaster.Agenda;
import TecMaster.Cliente;
import TecMaster.Empresa;
import TecMaster.GDA;
import TecMaster.Equipamentos.AparelhoDeSom;
import TecMaster.Equipamentos.Computador;
import TecMaster.Equipamentos.Dvd;
import TecMaster.Equipamentos.Equipamento;
import TecMaster.Equipamentos.Tv;
import TecMaster.Equipamentos.VideoGame;

/**
 * Classe reponsavel pela tela de Opcoes do programa.
 */

public class Opcoes extends JFrame implements ActionListener {
	private static final long serialVersionUID = 1L;
	private JPanel panel, panelCliente, panelEquipamento, panelRelatorio;
	private AbstractButton botaoCadastrarCliente, botaoCadastrarEquipamento,
			botaoConsultarEquipamento, botaoConsultarCliente,
			botaoRelatorioCliente, botaoRelatorioEmpresa, botaoSair;
	private String[] relatorios = { "Data", "Defeito", "Lista de Espera",
			"Tipo do Equipamento", "Garantia" };
	private String[] tipos = { "Aparelho de Som", "Computador", "DVD", "TV",
			"Video Game" };
	private Empresa<Equipamento> empresa;
	private Agenda<Equipamento> agenda;
	private final int TAMANHO_MAX_AGENDA = 5;
	private GDA<Equipamento> gda = new GDA<Equipamento>();
	private String Agenda = "Agenda.dat";

	/**
	 * Construtor de Opcoes
	 * 
	 * @throws FileNotFoundException
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public Opcoes() throws FileNotFoundException, IOException,
			ClassNotFoundException {
		super("TecMaster");
		setIconImage(Toolkit.getDefaultToolkit().getImage(
				getClass().getResource("/imagens/TM.png")));
		this.empresa = new Empresa<Equipamento>();
		if (gda.verificaArquivos(Agenda)) {
			this.agenda = gda.leArquivosAgenda();
		} else {
			this.agenda = new Agenda<Equipamento>();
			gda.guardaArquivos(this.agenda, Agenda);
		}

		panel = new JPanel(null);
		panel.setBackground(Color.LIGHT_GRAY);
		setBounds(new java.awt.Rectangle(0, 0, 400, 500));
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add(panel, BorderLayout.CENTER);

		panelCliente = new JPanel(null);
		panelCliente.setBackground(Color.LIGHT_GRAY);
		panelCliente.setSize(380, 100);
		panelCliente.setBounds(7, 20, 380, 100);
		panelCliente.setBorder(new TitledBorder("Cliente"));

		botaoCadastrarCliente = new JButton("Cadastrar");
		botaoCadastrarCliente.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/user_add.png")));
		panelCliente.add(botaoCadastrarCliente);
		botaoCadastrarCliente.setBounds(30, 38, 140, 30);
		botaoCadastrarCliente.addActionListener(this);

		botaoConsultarCliente = new JButton("Consultar");
		botaoConsultarCliente.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/user_go.png")));
		panelCliente.add(botaoConsultarCliente);
		botaoConsultarCliente.setBounds(210, 38, 140, 30);
		botaoConsultarCliente.addActionListener(this);

		panel.add(panelCliente);

		panelEquipamento = new JPanel(null);
		panelEquipamento.setBackground(Color.LIGHT_GRAY);
		panelEquipamento.setSize(380, 100);
		panelEquipamento.setBounds(7, 135, 380, 100);
		panelEquipamento.setBorder(new TitledBorder("Equipamento"));

		botaoCadastrarEquipamento = new JButton("Cadastrar");
		botaoCadastrarEquipamento.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/monitor_add.png")));
		panelEquipamento.add(botaoCadastrarEquipamento);
		botaoCadastrarEquipamento.setBounds(30, 38, 140, 30);
		botaoCadastrarEquipamento.addActionListener(this);

		botaoConsultarEquipamento = new JButton("Consultar");
		botaoConsultarEquipamento.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/monitor_go.png")));
		panelEquipamento.add(botaoConsultarEquipamento);
		botaoConsultarEquipamento.setBounds(210, 38, 140, 30);
		botaoConsultarEquipamento.addActionListener(this);

		panel.add(panelEquipamento);

		panelRelatorio = new JPanel(null);
		panelRelatorio.setBackground(Color.LIGHT_GRAY);
		panelRelatorio.setSize(380, 100);
		panelRelatorio.setBounds(7, 250, 380, 100);
		panelRelatorio.setBorder(new TitledBorder("Relatorio"));

		botaoRelatorioCliente = new JButton("Cliente");
		botaoRelatorioCliente.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/table_go.png")));
		panelRelatorio.add(botaoRelatorioCliente);
		botaoRelatorioCliente.setBounds(30, 38, 140, 30);
		botaoRelatorioCliente.addActionListener(this);

		botaoRelatorioEmpresa = new JButton("Empresa");
		botaoRelatorioEmpresa.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/table_multiple.png")));
		panelRelatorio.add(botaoRelatorioEmpresa);
		botaoRelatorioEmpresa.setBounds(210, 38, 140, 30);
		botaoRelatorioEmpresa.addActionListener(this);

		panel.add(panelRelatorio);

		botaoSair = new JButton("Sair");
		botaoSair.setIcon(new ImageIcon(getClass().getResource(
				"/imagens/cancel.png")));
		panel.add(botaoSair);
		botaoSair.setBounds(125, 390, 130, 30);
		botaoSair.addActionListener(this);

		pack();
		setSize(400, 500);
		setResizable(false);
		setLocationRelativeTo(null);
		setVisible(true);
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosing(java.awt.event.WindowEvent evt) {
				int saida = JOptionPane.showConfirmDialog(null,
						"Tem certeza que deseja sair ?", "Sair",
						JOptionPane.YES_NO_OPTION);
				if (saida == 0)
					System.exit(0);
			}
		});

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == botaoCadastrarCliente) {
			if (agenda.numeroDeEquipamentosNaFila() < TAMANHO_MAX_AGENDA) {
				new CadastrarCliente(this);
				setVisible(false);

			} else {
				JOptionPane.showMessageDialog(null, "Agenda cheia!", "ERRO!",
						JOptionPane.ERROR_MESSAGE);
			}
		}
		if (e.getSource() == botaoConsultarCliente) {
			String cpfDoCliente = JOptionPane.showInputDialog(null,
					"CPF do Cliente (Apenas numeros):",
					"TecMaster - Consultar cliente",
					JOptionPane.QUESTION_MESSAGE);
			if (cpfDoCliente != null) {
				try {
					Cliente cliente = empresa.localizaCliente(cpfDoCliente);
					List<Equipamento> listEquip = empresa
							.getEquipamentosDoCliente(cliente);
					new ConsultaCliente(this, cliente, listEquip);
				} catch (Exception excConsultaCliente) {
					JOptionPane.showMessageDialog(null, excConsultaCliente
							.getMessage(), "ERRO!", JOptionPane.ERROR_MESSAGE);
				}
			}
		}
		if (e.getSource() == botaoCadastrarEquipamento) {
			if (agenda.numeroDeEquipamentosNaFila() < TAMANHO_MAX_AGENDA) {
				String cpf = JOptionPane.showInputDialog(null,
						"CPF do Cliente (Apenas numeros):",
						"TecMaster - Cadastrar Equipamento",
						JOptionPane.QUESTION_MESSAGE);
				if (cpf != null) {
					try {
						new CadastrarEquipamento(this, null, cpf);
						setVisible(false);
					} catch (Exception eCadastrarEquipamento) {
						JOptionPane.showMessageDialog(null,
								eCadastrarEquipamento.getMessage(), "ERRO!",
								JOptionPane.ERROR_MESSAGE);
					}
				}
			} else {
				JOptionPane.showMessageDialog(null, "Agenda cheia!", "ERRO!",
						JOptionPane.ERROR_MESSAGE);
			}
		}
		if (e.getSource() == botaoConsultarEquipamento) {
			String codigoEquip = JOptionPane.showInputDialog(null,
					"Codigo do Equipamento:",
					"TecMaster - Consultar equipamento",
					JOptionPane.QUESTION_MESSAGE);
			if (codigoEquip != null) {
				try {
					Equipamento equip = empresa.getEquipamento(codigoEquip);
					Cliente c = empresa.getClientePeloEquipamento(equip);
					new ConsultaEquipamento(this, equip, c, agenda);
				} catch (Exception eConsultaEquipamento) {
					JOptionPane.showMessageDialog(null, eConsultaEquipamento
							.getMessage(), "ERRO!", JOptionPane.ERROR_MESSAGE);
				}
			}
		}

		if (e.getSource() == botaoRelatorioCliente) {
			String codigoEquipamento = JOptionPane.showInputDialog(null,
					"Codigo do equipamento:", "TecMaster - Emitir Relatorio",
					JOptionPane.QUESTION_MESSAGE);
			if (codigoEquipamento != null) {
				try {
					Equipamento equip = empresa
							.getEquipamento(codigoEquipamento);
					Cliente c = empresa.getClientePeloEquipamento(equip);
					new RelatorioDoCliente(this, equip, c);
				} catch (Exception eConsultaEquipamento) {
					JOptionPane.showMessageDialog(null, eConsultaEquipamento
							.getMessage(), "ERRO!", JOptionPane.ERROR_MESSAGE);
				}
			}
		}

		if (e.getSource() == botaoRelatorioEmpresa) {
			String relatorioSelecionado = (String) JOptionPane.showInputDialog(
					null, " Escolha o relatorio:",
					"TecMaster - Emitir Relatorio",
					JOptionPane.QUESTION_MESSAGE, null, relatorios,
					relatorios[0]);
			if (relatorioSelecionado != null) {
				if (relatorioSelecionado.equals("Data")) {
					String stringData = JOptionPane.showInputDialog(null,
							"Data (dd/mm/aaaa):",
							"TecMaster - Emitir Relatorio(Data)",
							JOptionPane.QUESTION_MESSAGE);
					if (stringData != null) {
						try {
							int dia = Integer.parseInt(stringData.substring(0,
									2));
							int mes = Integer.parseInt(stringData.substring(3,
									5));
							int ano = Integer.parseInt(stringData.substring(6));
							Calendar data = new GregorianCalendar(ano, mes - 1,
									dia);
							new RelatorioEmpresa(this).porData(data);
						} catch (Exception eData) {
							JOptionPane.showMessageDialog(null,
									"Formato de data Invalido!", "ERRO!",
									JOptionPane.ERROR_MESSAGE);
						}
					}
				}
				if (relatorioSelecionado.equals("Lista de Espera")) {
					new RelatorioEmpresa(this).porEspera();
				}
				if (relatorioSelecionado.equals("Defeito")) {
					try {
						new RelatorioEmpresa(this).porDefeito();
					} catch (FileNotFoundException e1) {
						e1.printStackTrace();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
				if (relatorioSelecionado.equals("Garantia")) {
					new RelatorioEmpresa(this).porGarantia();
				}

				if (relatorioSelecionado.equals("Tipo do Equipamento")) {
					String tipoSelecionado = (String) JOptionPane
							.showInputDialog(null, " Escolha o Tipo:",
									"TecMaster - Emitir Relatorio - Tipo ?",
									JOptionPane.QUESTION_MESSAGE, null, tipos,
									tipos[0]);
					if (tipoSelecionado != null) {
						if (tipoSelecionado.equals("Aparelho de Som"))
							new RelatorioEmpresa(this)
									.porTipo(AparelhoDeSom.class);
						if (tipoSelecionado.equals("Computador"))
							new RelatorioEmpresa(this)
									.porTipo(Computador.class);
						if (tipoSelecionado.equals("DVD"))
							new RelatorioEmpresa(this).porTipo(Dvd.class);
						if (tipoSelecionado.equals("TV"))
							new RelatorioEmpresa(this).porTipo(Tv.class);
						if (tipoSelecionado.equals("Video Game"))
							new RelatorioEmpresa(this).porTipo(VideoGame.class);
					}
				}
			}
		}

		if (e.getSource() == botaoSair) {
			int saida = JOptionPane.showConfirmDialog(null,
					"Tem certeza que deseja sair ?", "Sair",
					JOptionPane.YES_NO_OPTION);
			if (saida == 0) {
				try {
					gda.guardaArquivos(empresa.mapaClientesEquipamentos,
							empresa.Clientes);
				} catch (FileNotFoundException e1) {
					e1.printStackTrace();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				System.exit(0);
			}
		}

	}

	/**
	 * Retorna o total de dias na agenda
	 * 
	 * @return o total de dias na agenda
	 */
	public int pegaDiasNaAgenda() {
		return agenda.getTotalDias();

	}

	/**
	 * Adiciona um equipamento na agenda
	 * 
	 * @param equip
	 *            o equipamento que se quer adicionar na genda
	 * @throws Exception
	 */
	public void adicionaNaAgenda(Equipamento equip) throws Exception {
		agenda.addEquipamento(equip);
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
				"Agenda.dat"));
		out.writeObject(this.agenda);
		out.close();

	}

	/**
	 * Cdastra um cliente e se equipamento na empresa
	 * 
	 * @param c
	 *            o cliente a ser adicionado
	 * @param e
	 *            o equipamento a ser adicionado
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void cadastraNaEmpresa(Cliente c, Equipamento e)
			throws FileNotFoundException, IOException {
		empresa.addClienteEEquipamento(c, e);
	}

	/**
	 * Cadastra um equipamento na empresa de um cliente ja cadastrado
	 * 
	 * @param cpf
	 *            o cpf do cliente ja cadastrado
	 * @param e
	 *            o equipamento que se quer adicionar
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void cadastraEquipamentoNaEmpresa(String cpf, Equipamento e)
			throws FileNotFoundException, IOException {
		empresa.addEquipamento(cpf, e);
	}

	/**
	 * localiza um cliente na empresa pelo cpf
	 * 
	 * @param cpf
	 *            cpf do cliente a ser localizado
	 * @return o Cliente procurado
	 * @throws Exception
	 *             caso o cliente n�o exista
	 */
	public Cliente localizaClientePeloCpf(String cpf) throws Exception {
		return empresa.localizaCliente(cpf);
	}

	/**
	 * Checa se um cliente ja esta cadastrado na empresa
	 * 
	 * @param c
	 *            o cliente a ser checado
	 * @return true se o cliente est� cadastrado
	 */
	public boolean checaClienteJaCadastrado(Cliente c) {
		return empresa.checaClienteJaCadastrado(c);
	}

	/**
	 * Retorna a lista de equipamentos com estado CONSERTADO, a partir da data
	 * passada como parametro, da empresa.
	 * 
	 * @param data
	 *            a data do conserto.
	 * @return a lista de equipamentos com estado CONSERTADO, a partir da data
	 *         passada como parametro, da empresa.
	 */
	public List<Equipamento> getListaEquipData(Calendar data) {
		return empresa.ordenacaoPorData(data);
	}

	/**
	 * Retorna um mapa de clientes e seus equipamentos com estado NA_FILNA ou
	 * NO_TECNICO.
	 * 
	 * @return uma lista de equipamentos com estado NA_FILNA ou NO_TECNICO.
	 */
	public Map<Cliente, ArrayList<Equipamento>> getListaDeEspera() {
		return empresa.ordenacaoNomeCliente();
	}

	/**
	 * Retorna um mapa de um tipo de equipamento que possui o defeito mais
	 * apresentado em seu tipo e como valor um inteiro com a quatidade de
	 * defeitos desse tipo apresentado.
	 * 
	 * @return um mapa de um tipo de equipamento que possui o defeito mais
	 *         apresentado em seu tipo e como valor um inteiro com a quatidade
	 *         de defeitos desse tipo apresentado.
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public HashMap<Equipamento, Integer> getListaDeMaioresDefeitos()
			throws FileNotFoundException, IOException {
		return empresa.ordenacaoDefeitoApresentado();
	}

	/**
	 * Retorna uma uma lista de 2 mapas, o primeiro mapa da lista contem o
	 * equipamento(na garantia) e seu dono, o segundo mapa contem os mesmos
	 * elementos porem com equipamentos que nao estao na garantia.
	 * 
	 * @return uma uma lista de 2 mapas, o primeiro mapa da lista contem o
	 *         equipamento(na garantia) e seu dono, o segundo mapa contem os
	 *         mesmos elementos porem com equipamentos que nao estao na
	 *         garantia.
	 */
	public ArrayList<HashMap<Equipamento, Cliente>> getListaSeparadaPorGarantia() {
		return empresa.ordencaoGarantia();
	}

	/**
	 * Retorna um mapa de cliente e seus equipamentos de um determinado tipo
	 * passado como parametro.
	 * 
	 * @param classe
	 *            uma classe herdada de equipamento.
	 * @return um mapa de cliente e seus equipamentos de um determinado tipo
	 *         passado como parametro.
	 */
	public Map<Cliente, ArrayList<Equipamento>> getListaDeTipo(Object classe) {
		return empresa.ordenacaoTipoAparelho(classe);
	}

}
